package de.ishuo.netzclubminutecounter;

import java.awt.Color;
import java.awt.Font;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

public class ViewController extends JFrame {
	
	private static final long serialVersionUID = -3067262471094902007L;
	private final static File[] EMPTY_FILE_ARRAY = new File[] {};
	
	private JPanel panel;
	private JLabel minuteLabel;
	private JLabel textLabel;
	private Color defaultBackgroundColor;
	private Color droppableBackgroundColor;
	
	private ExecutorService pool;
	private boolean counterInitialized = false;
	
	public ViewController() {
		setSize(200, 170);
		setLocationRelativeTo(null);
		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		setTitle("Netzclub Minute Counter");
		if (!Main.isOnMac()) {
			Image icon = Toolkit.getDefaultToolkit().getImage("res/logo/nmc-logo.png");
			setIconImage(icon);
		}
		
		
		panel = createPanel();
		defaultBackgroundColor = panel.getBackground();
		droppableBackgroundColor = defaultBackgroundColor.darker();
		
		getContentPane().add(panel);
		setVisible(true);
		
		pool = Executors.newSingleThreadExecutor();
	}

	private JPanel createPanel() {
		JPanel panel = new JPanel();
		panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
		
		makeDragAndDroppable(panel);
		addWidgets(panel);
		
		return panel;
	}


	private void makeDragAndDroppable(JPanel panel) {
		new DropTarget(panel, new FileDropTargetListener());
	}

	private final class FileDropTargetListener extends DropTargetAdapter {
		@Override
		public void drop(DropTargetDropEvent dtde) {
			Transferable transferable = dtde.getTransferable();
			
			DataFlavor[] flavors = dtde.getCurrentDataFlavors();
			for (DataFlavor flavor : flavors) {
				if (flavor.isFlavorJavaFileListType()) {
					dtde.acceptDrop(DnDConstants.ACTION_COPY);
					try {
						@SuppressWarnings("unchecked")
						List<File> files = (List<File>) transferable.getTransferData(flavor);
						countAndShowMinutes(files);
					} catch (UnsupportedFlavorException e) {
						// Should not happen
					} catch (IOException e) {
						e.printStackTrace();
					}
					
					dtde.dropComplete(true);
					panel.setBackground(defaultBackgroundColor);
					return;
				}
			}
		}

		@Override
		public void dragOver(DropTargetDragEvent dtde) {		
			DataFlavor[] flavors = dtde.getCurrentDataFlavors();
			for (DataFlavor flavor : flavors) {
				if (flavor.isFlavorJavaFileListType()) {
					if (Main.isOnMac()) {
						dtde.acceptDrag(DnDConstants.ACTION_COPY);
					} else {
						dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
					}
					
					panel.setBackground(droppableBackgroundColor);
					return;
				}
			}
			dtde.rejectDrag();
		}

		@Override
		public void dragExit(DropTargetEvent dte) {
			panel.setBackground(defaultBackgroundColor);
		}	
	}
	
	private void countAndShowMinutes(final List<File> files) {
		if (!counterInitialized) {
			minuteLabel.setText(" ");
			textLabel.setText("Rechne...");
		}
		
		pool.execute(new CountMinuteRunnable(files));
	}
	
	private final class CountMinuteRunnable implements Runnable {
		
		private final List<File> files = new ArrayList<File>();

		private CountMinuteRunnable(List<File> files) {
			extractFiles(files.toArray(EMPTY_FILE_ARRAY));
		}

		// Recursively extract all files in case a folder is given
		private void extractFiles(File[] files) {
			for (File file : files) {
				if (file.isDirectory()) {
					File[] filesInDeeperLevel = file.listFiles();
					extractFiles(filesInDeeperLevel);
				} else {
					this.files.add(file);
				}
			}	
		}

		@Override
		public void run() {
			int minutes = 0;
			for (File file : files) {
				minutes += MinuteCounter.countMinute(file);
			}
			if (minutes <= 0) {
				minuteLabel.setText("0");
				textLabel.setText("Min. Richtige Datei?");
			} else {
				minuteLabel.setText(String.valueOf(minutes));
				textLabel.setText("Min. verbraucht.");
			}
			counterInitialized = true;
		}
	}
	

	private void addWidgets(JPanel panel) {
		panel.add(Box.createVerticalGlue());
		
		minuteLabel = new SetTextWithAnimationLabel("X");

		minuteLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 80));
		minuteLabel.setAlignmentX(CENTER_ALIGNMENT);
		panel.add(minuteLabel);
		
		textLabel = new JLabel("Entgeldnachweise hier ablegen");
		textLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 12));
		textLabel.setAlignmentX(CENTER_ALIGNMENT);
		panel.add(textLabel);
		
		panel.add(Box.createVerticalStrut(10));
		panel.add(Box.createVerticalGlue());
	}
	
	
}
